package com.yx.fx.sys.web.business;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yx.fx.common.model.response.Outcome;
import com.yx.fx.sys.db.entity.SysRole;
import com.yx.fx.sys.db.entity.SysUserRole;
import com.yx.fx.sys.db.service.SysRoleService;
import com.yx.fx.sys.db.service.SysUserRoleService;
import com.yx.fx.sys.web.model.UserInfo;
import com.yx.fx.sys.web.model.find.FindRolePage;
import com.yx.fx.sys.web.model.save.SaveRole;
import com.yx.fx.sys.web.model.update.ResetUserRole;
import com.yx.fx.sys.web.model.update.UpdateRole;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

import static com.yx.fx.common.constant.BaseConstant.ZERO;


/**
 * @author 杨智杰
 * @since 2021/8/25 11:03
 */
@Service
public class SysRoleBusiness {

    @Resource
    private SysRoleService sysRoleService;

    @Resource
    private SysUserBusiness sysUserBusiness;

    @Resource
    private SysUserRoleService sysUserRoleService;

    /**
     * 添加
     *
     * @param param 角色数据
     * @return 是否成功
     */
    public Outcome save(SaveRole param) {
        UserInfo userInfo = sysUserBusiness.getUserInfo();
        SysRole sysRole = Convert.convert(SysRole.class, param);
        sysRole.setCreateBy(userInfo.getId());
        if (sysRoleService.count(new QueryWrapper<SysRole>().lambda()
                .eq(SysRole::getName, param.getName())) > ZERO) {
            return Outcome.failure("角色名重复!");
        }
        return Outcome.status(sysRoleService.save(sysRole));
    }

    /**
     * 修改
     *
     * @param param 角色数据
     * @return 是否成功
     */
    public Outcome update(UpdateRole param) {
        UserInfo userInfo = sysUserBusiness.getUserInfo();
        SysRole sysRole = Convert.convert(SysRole.class, param);
        sysRole.setUpdateBy(userInfo.getId());
        if (sysRoleService.count(new QueryWrapper<SysRole>().lambda()
                .eq(SysRole::getName, param.getName())
                .ne(SysRole::getId, param.getId())) > ZERO) {
            return Outcome.failure("角色名重复!");
        }
        return Outcome.status(sysRoleService.updateById(sysRole));
    }

    /**
     * 删除
     *
     * @param id 根据Id删除
     * @return 是否成功
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(List<Long> id) {
        UserInfo userInfo = sysUserBusiness.getUserInfo();
        boolean updateBatchById = sysRoleService.updateBatchById(Convert.toList(SysRole.class, id.stream()
                .map(i -> new SysRole().setUpdateBy(userInfo.getId()).setId(i)).collect(Collectors.toList())));
        boolean removeByIds = sysRoleService.removeByIds(id);
        return updateBatchById && removeByIds;
    }

    /**
     * 分页
     *
     * @param param 分页条件
     * @return 分页数据
     */
    public IPage<SysRole> page(FindRolePage param) {
        return sysRoleService.page(new Page<>(param.getCurrent(), param.getSize()), new QueryWrapper<SysRole>().lambda()
                .eq(ObjectUtil.isNotNull(param.getId()), SysRole::getId, param.getId())
                .eq(ObjectUtil.isNotNull(param.getStatus()), SysRole::getStatus, param.getStatus())
                .like(StrUtil.isNotBlank(param.getName()), SysRole::getName, param.getName())
                .orderByDesc(SysRole::getCreateTime));
    }

    /**
     * 重置用户角色列表
     *
     * @param param 用户角色关联
     * @return 是否成功
     */
    @Transactional(rollbackFor = Exception.class)
    public Outcome reset(ResetUserRole param) {
        boolean remove = sysUserRoleService.remove(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getUserId, param.getUserId()));
        boolean save = sysUserRoleService.saveBatch(param.getRoleIds().stream().map(id -> new SysUserRole()
                .setUserId(param.getUserId()).setRoleId(id)).collect(Collectors.toList()));
        return Outcome.status(remove && save);
    }
}
